/*    file: main.cpp
 *    desc:
 * 
 * created: 2016-04-06
 *  author: chuanjiang.zh@qq.com
 * company: 
 */

#include <stdio.h>
#include <iostream>

#include "BasicType.h"
#include "RtmpCaster.h"
#include "Ffmpeg.h"
#include "SharedPtr.h"
#include "TFileUtil.h"
#include <assert.h>
#include "TByteBuffer.h"
#include "LoopReader.h"
#include "TimePoint.h"

struct Application
{
public:
	Application()
	{
		av_register_all();
		avformat_network_init();

		rtmpcaster_init();
	}

	~Application()
	{
		rtmpcaster_quit();
	}
};

void DemoCasterEventCallback(const CasterEvent* event, void* context)
{
	printf("mtp event. type:%d,%s, name:%s\n",
		event->type, rtmpcaster_get_event_name(event->type),
		event->name);
}


int main(int argc, char** argv)
{
	std::string filename = "rtsp://admin:sjld16301@192.168.3.65/";
	std::string	url = "rtmp://192.168.11.92/live/demo";

	if (argc > 1)
	{
		filename = argv[1];
	}

	if (argc > 2)
	{
		url = argv[2];
	}

	Application app;

	LoopReader reader;
	int rc = reader.open(filename.c_str());
	if (rc != 0)
	{
		return rc;
	}

	MFormat fmt;
	memset(&fmt, 0, sizeof(fmt));
	fmt.width = reader.m_width;
	fmt.height = reader.m_height;
	fmt.framerate = reader.m_fps;
	fmt.codec = reader.m_codec;
	fmt.vProp = (uint8_t*)(reader.m_prop.c_str());
	fmt.vPropSize = reader.m_prop.size();
	//fmt.clockRate = AV_TIME_BASE;
	fmt.clockRate = reader.m_clockRate;

	fmt.channels = reader.m_channels;
	fmt.sampleRate = reader.m_sampleRate;
	fmt.audioCodec = reader.m_acodec;
	fmt.config = (uint8_t*)(reader.m_config.c_str());
	fmt.configSize = reader.m_config.size();
	//fmt.audioRate = AV_TIME_BASE;
	fmt.audioRate = reader.m_audioRate;

	std::string sps;
	std::string pps;
	std::string sprop;
	comn::ByteBuffer videoBuffer;

	caster_t handle = -1;
	rc = rtmpcaster_open(&handle, url.c_str(), &fmt);

	rtmpcaster_set_event_callback(handle, DemoCasterEventCallback, NULL);

	int64_t tmStart = av_gettime_relative();

	int count = 0;
	av::TimePoint	startPoint;

	while (true)
	{
		count ++;
		if (count >100000)
		{
			break;
		}

		AVPacket pkt;
		av_init_packet(&pkt);

		rc = reader.read(pkt);
		if (rc != 0)
		{
			break;
		}

		int clockRate = pkt.stream_index == 0 ? fmt.clockRate : fmt.audioRate;
		av::TimePoint tp(av_gettime(), pkt.dts * AV_TIME_BASE / clockRate);
		if (!startPoint.isSet())
		{
			startPoint = tp;
		}

		MPacket mpkt;
		memset(&mpkt, 0, sizeof(mpkt));
		mpkt.type = reader.isVideo(pkt) ? MTYPE_VIDEO : MTYPE_AUDIO;;
		mpkt.data = pkt.data;
		mpkt.size = pkt.size;
		mpkt.pts = pkt.dts;
		mpkt.duration = pkt.duration;
		mpkt.flags = pkt.flags;

		//printf("type:%d, size:%d, pts:%lld\n", mpkt.type, mpkt.size, mpkt.pts);

		rtmpcaster_write(handle, &mpkt);

		av_packet_unref(&pkt);

		if (!reader.isLive())
		{
			int64_t elapse = tp.getOffset(startPoint);
			if (elapse > 0 && elapse < AV_TIME_BASE)
			{
				av_usleep(elapse);
			}
		}
	}

	std::cout << "enter any key to exit.\n";

	std::cin.get();

	rtmpcaster_close(handle);
	handle = 0;

	return 0;
}




